package cn.skylark.wcm.controller;

import cn.skylark.wcm.common.splitter.doc.POIConverter;
import cn.skylark.wcm.common.splitter.doc.SplitterArray;
import cn.skylark.wcm.common.splitter.doc.TxtSplitter;
import cn.skylark.wcm.common.splitter.doc.Util;
import cn.skylark.wcm.common.splitter.docx.docxSplitter;
import cn.skylark.wcm.common.util.Constants;
import cn.skylark.wcm.common.util.PdfUtils;
import cn.skylark.wcm.common.util.ReturnMap;
import cn.skylark.wcm.common.util.UploadHelper;
import cn.skylark.wcm.entity.Filetable;
import cn.skylark.wcm.entity.Tenan;
import cn.skylark.wcm.entity.User;
import cn.skylark.wcm.service.*;
import com.github.pagehelper.PageInfo;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 文件管理控制器
 *
 * @author 翟亚兴
 * @since 2017/12/29
 */
@RestController
@RequestMapping("/filemanager")
public class FileManagerController {
    Logger logger=LoggerFactory.getLogger(FileManagerController.class);
    @Autowired
    FileManagerService fileManagerService;
    @Autowired
    FileUploadService fileUploadService;
    @Autowired
    TenanService tenanService;
    @Autowired
    TenanPropertyService tenanPropertyService;
    @Autowired
    RecycleService recycleService;

    /**
     * 文件表格中的逻辑删除
     * 业务：当点击表格中的删除按钮式执行该方法，先进行判断是文件还是文件夹，
     * 是文件的话直接进行逻辑删除，是文件夹的话对他下面的所有文件进行删除，
     * 根据文件的id 进行单个的逻辑删除，如果成功返回0 ，不成功返回2
     *
     * @param id 文件id
     * @return
     */
    @RequestMapping(value="/delete")
    public String delete(Integer id) {
        logger.info("传入参数" + id);
        ReturnMap returnMap=new ReturnMap();
        try {
            Filetable filetable=fileManagerService.selectById(id);
            Integer type=filetable.getType();
            fileManagerService.delete(id, type);
            returnMap.setFlg(0);
            returnMap.setMessage("删除成功");
        } catch (Exception e) {
            logger.info("异常类型是;" + e);
            e.printStackTrace();
            returnMap.setFlg(2);
            returnMap.setMessage("删除失败");
        }
        return returnMap.ReturnMap();
    }

    /**
     * 文件的批量删除
     *
     * @param ids 数组id
     * @return
     */
    @RequestMapping(value="/batchDelete")
    public String batchDelete(String[] ids) {
        logger.info("传入参数" + ids);
        ReturnMap returnMap=new ReturnMap();
        try {
            fileManagerService.batchDelete(ids);
            returnMap.setFlg(0);
            returnMap.setMessage("删除成功");
        } catch (Exception e) {
            logger.info("异常类型是;" + e);
            e.printStackTrace();
            returnMap.setFlg(2);
            returnMap.setMessage("删除失败");
        }
        return returnMap.ReturnMap();
    }

    /**
     * 完全删除文件
     *
     * @param fileid 文件id
     * @return
     */
    @RequestMapping(value = "/completeDelete")
    public String completeDelete(Integer fileid, User user) {
        ReturnMap returnMap = new ReturnMap();
        try {
            //通过文件的id获得此id下的所有属性
            Filetable filetable = fileManagerService.selectById(fileid);
            String filename = filetable.getFilename();
            //调用完全删除的方法
            fileUploadService.deleteFile(filename, user);
            logger.info("删除结束");
            returnMap.setFlg(0);
            returnMap.setMessage("删除成功");
        } catch (Exception e) {
            logger.info("异常类型是;" + e);
            e.printStackTrace();
            returnMap.setFlg(2);
            returnMap.setMessage("删除失败");
        }
        return returnMap.ReturnMap();
    }


    /**
     * 通过用户id和租户id 获取文件的初始化列表
     *
     * @param filetable 文件表的实体类
     * @return
     */
    @RequestMapping(value = "/selectInitFileListByParameter")
    public Map<String, Object> selectInitFileListByParameter(Filetable filetable, HttpServletRequest request,
                                                             @RequestParam(required = false, defaultValue = "1") int start,
                                                             @RequestParam(required = false, defaultValue = "10") int length) {
        logger.info("传入参数" + filetable);
        String searchValue = request.getParameter("search[value]");
        String flag = request.getParameter("flag");
        logger.info("search:" + searchValue);
        filetable.setType(0);
        Map<String, Object> map = new HashMap<>();
        try {
            //通过用户的id获取文件列表
            PageInfo<Filetable> pageInfo = fileManagerService.selectInitFileListByParameter(filetable, flag, start, length, searchValue);
            map.put("recordsTotal", pageInfo.getTotal());
            map.put("recordsFiltered", pageInfo.getTotal());
            map.put("data", pageInfo.getList());
            map.put("flg", 0);
            map.put("message", "获取用户文件列表成功");
        } catch (Exception e) {
            logger.info("异常类型是;" + e);
            e.printStackTrace();
            map.put("flg", 2);
            map.put("message", "获取用户文件列表失败");
        }
        return map;
    }

    /**
     * 通过文件夹的id获取每次点击文件列表得到下层的文件夹
     *
     * @param id 文件表的id
     * @return
     */
    @RequestMapping(value = "/selectByPageFolder")
    public Map<String, Object> selectByPageFolder(Integer id, HttpServletRequest request,
                                                  @RequestParam(required = false, defaultValue = "1") int start,
                                                  @RequestParam(required = false, defaultValue = "10") int length) {
        Map<String, Object> map = new HashMap<String, Object>();
        String searchValue = request.getParameter("search[value]");
        String flag = request.getParameter("flag");
        try {
            //通过文件的id获取文件列表
            Filetable filetable = fileManagerService.selectById(id);
            PageInfo<Filetable> pageInfo = fileManagerService.selectByPageFolder(filetable, flag, start, length, searchValue);
            map.put("recordsTotal", pageInfo.getTotal());
            map.put("recordsFiltered", pageInfo.getTotal());
            map.put("data", pageInfo.getList());
            String localpath = "";
            String path = "";
            if (filetable.getLocalpath() == null || "".equals(filetable.getLocalpath())) {
                localpath = ">";
            } else {
                String orginLocalpath = filetable.getLocalpath().replaceAll("/", ">");
                localpath = ">" + orginLocalpath;
                logger.info("localpath" + localpath);
            }
            path = localpath + filetable.getFilename();
            map.put("localpath", path);
            map.put("flg", 0);
            map.put("message", "获取用户文件列表成功");
        } catch (Exception e) {
            logger.info("异常类型是;" + e);
            e.printStackTrace();
            map.put("flg", 2);
            map.put("message", "获取用户文件列表失败");
        }
        return map;
    }

    /**
     * 新建文件夹
     * 业务： 前端传过来路径，分别以locapath和filename来传
     * 先判断文件夹是否存在，然后进行添加的操作。如果在根目录下新建，则localpath为空
     * 只传filename，如果在文件夹下建文件夹，则他的前面路径作为localpath来传，形式为：src/a/b/
     * 本级路径作为filename来传。形式如：c
     *
     * @param filetable 文件表的实体类
     * @return
     */
    @RequestMapping(value = "/saveFolder")
    public String saveFolder(Filetable filetable, HttpServletRequest request) {
        logger.info("传入参数" + filetable);
        ReturnMap returnMap = new ReturnMap();
        String fatherid = request.getParameter("fatherid");
        String father;
        try {
            if (fatherid == null || "".equals(fatherid)) {
                father = "";
            } else {
                Filetable filetableMessage = fileManagerService.selectById(Integer.valueOf(fatherid));
                if((filetableMessage.getUserid()==filetable.getUserid())&&(filetableMessage.getTenanid()==filetable.getTenanid())){
                    father = filetableMessage.getLocalpath() + filetableMessage.getFilename() + "/";
                }else{
                    //文件夹用户信息，与操作者信息不同，更改
                    filetable.setUserid(filetableMessage.getUserid());
                    filetable.setTenanid(filetableMessage.getTenanid());
                    father = filetableMessage.getLocalpath() + filetableMessage.getFilename() + "/";
                }
            }
            //先判断这个文件夹是否存在，如果存在，返回提示信息
            filetable.setLocalpath(father);
            filetable.setFilename(filetable.getFilename());
            filetable.setType(0);
            Filetable r = fileManagerService.selectByParameter(filetable);
            //如果存在的话返回信息
            if (r != null) {
                returnMap.setFlg(1);
                returnMap.setMessage("该文件夹已存在！");
                return returnMap.ReturnMap();
            }

            //通过前端所传的数据，然后进行数据的添加，locapath 表示他的上层目录
            fileManagerService.saveFolder(filetable);
            returnMap.setFlg(0);
            returnMap.setMessage("新建文件夹成功");
        } catch (Exception e) {
            logger.info("异常类型是;" + e);
            e.printStackTrace();
            returnMap.setFlg(2);
            returnMap.setMessage("新建文件夹失败");
        }
        return returnMap.ReturnMap();
    }

    /**
     * 获取该用户的视频列表
     *
     * @param filetable 文件的实体类
     * @return
     */
    @RequestMapping(value = "/selectVideoListByParameter")
    public Map<String, Object> selectVideoListByParameter(Filetable filetable, HttpServletRequest request,
                                                          @RequestParam(required = false, defaultValue = "1") int start,
                                                          @RequestParam(required = false, defaultValue = "10") int length) {
        logger.info("参数传入===" + "filetable===" + filetable);
        Map<String, Object> map = new HashMap<>();
        String searchValue = request.getParameter("search[value]");
        String flag = request.getParameter("flag");
        logger.info("search:" + searchValue);
        filetable.setType(2);
        try {
            //通过用户的id获取文件列表
            PageInfo<Filetable> pageInfo = fileManagerService.selectVideoListByParameter(filetable, flag, start, length, searchValue);
            map.put("recordsTotal", pageInfo.getTotal());
            map.put("recordsFiltered", pageInfo.getTotal());
            map.put("data", pageInfo.getList());
            map.put("code", 0);
            map.put("message", "获取用户视频列表成功");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("code", 2);
            map.put("message", "获取用户视频列表失败");
        }
        return map;
    }

    /**
     * 文件库使用率
     *
     * @param tenanid 租户id
     * @return
     */
    @RequestMapping(value = "/filePercentage")
    public String filePercentage(Integer tenanid) {
        logger.info("参数传入" + tenanid);
        ReturnMap returnMap = new ReturnMap();
        try {
            //通过tenanid来获取该用户的储存大小
            Tenan tenan = tenanService.getStorageById(tenanid);
            //得到该租户的储存空间。
            Long storage = tenan.getStorage();
            //得到该租户的已经上传的文件空间大小。
            String totalSize = fileUploadService.getTotalSize(Integer.valueOf(tenanid));
            if (totalSize == null || "".equals(totalSize)) {
                totalSize = "0";
            }
            //然后算出使用率。
            DecimalFormat df = new DecimalFormat("0.0");//格式化小数
            String num = df.format((float) Long.valueOf(totalSize) / storage * 100);
            String percentage = num + "%";
            Map<String, Object> map = new HashMap<>();
            returnMap.setFlg(0);
            returnMap.setMessage("儲存空间使用率");
            logger.info("使用的空间==" + storage);
            logger.info("总容量===" + totalSize);
            logger.info("百分数==" + percentage);
            map.put("storage", storage);
            map.put("totalSize", totalSize);
            map.put("percentage", percentage);
            returnMap.setData(JSONObject.fromObject(map).toString());
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("异常类型是：" + e);
            returnMap.setFlg(2);
            returnMap.setMessage("儲存空间使用率计算错误");
        }
        return returnMap.ReturnMap();
    }

    /**
     * 上传文件
     *
     * @param request 接收文件的请求
     * @return
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public Map uploadFile(MultipartHttpServletRequest request,
                          @RequestParam(required = false, defaultValue = "1") int start,
                          @RequestParam(required = false, defaultValue = "10") int length) {
        Map<String, Object> map = new HashMap();
        try {
            logger.info("文件上传开始");
            MultiValueMap<String, MultipartFile> linkedHashMap = request.getMultiFileMap();
            //上传本地路径
            String localfilepath = request.getParameter("filepath");
            logger.info("filePath===" + localfilepath);
            String tenanid = request.getParameter("tenanid");
            String userid = request.getParameter("userid");
            String fatherid = request.getParameter("fatherid");
            logger.info("fatherid=====" + fatherid);
            String father;
            User user = new User();
            if (fatherid == null || "".equals(fatherid)) {
                father = "";
                //判断是否同一用户进行操作
                user.setId(Integer.valueOf(userid));
                user.setTenanid(Integer.valueOf(tenanid));
            } else {
                Filetable filetable = fileManagerService.selectById(Integer.valueOf(fatherid));
                father = filetable.getLocalpath() + filetable.getFilename() + "/";
                //判断是否同一用户进行操作
                Filetable filetableMessage=new Filetable();
                filetableMessage.setId(Integer.valueOf(fatherid));
                Filetable message=fileUploadService.getFiletable(filetableMessage);
                if((Integer.valueOf(userid)==message.getUserid())&&(Integer.valueOf(tenanid)==message.getTenanid())){
                    //传入用户信息，与父文件夹信息不同
                    user.setId(Integer.valueOf(userid));
                    user.setTenanid(Integer.valueOf(tenanid));
                }else {
                    //传入用户信息，与父文件夹信息不同
                    user.setId(message.getUserid());
                    user.setTenanid(message.getTenanid());
                }
            }
            //服务器临时目录
            String realPath = Constants.REALPATH;
            //上传文件取得
            List<MultipartFile> multipartFiles = UploadHelper.getFileSet(request, new String[]{".doc", ".pdf", ".docx"});
            if (linkedHashMap.get("uploadfile[]").size() != multipartFiles.size()) {
                map.put("code", 1);
                map.put("message", "文件类型不符");
                return map;
            }
            //遍历判断所传文件的大小
            long size=0;
            Set<String> set=new HashSet<>();
            String[] localpathlist=localfilepath.split("\\|");
            int i=0;
            for (MultipartFile multipartFile : multipartFiles) {
                size+=multipartFile.getSize();
                String filename;
                if (!"undefined".equals(localpathlist[i])) {
                    //如果不为undefined 就是相对路径
                    filename = father + "" + localpathlist[i];
                    set.add(filename);
                } else {
                    //如果是undefined 就是文件名 xx.xx
                    filename = father + "" + multipartFile.getOriginalFilename();
                    set.add(filename);
                }
                //判断文件是否存在
                if (!fileUploadService.selectFileRepeat(filename, Integer.valueOf(tenanid),
                        Integer.valueOf(userid), 1)) {
                    map.put("code", 1);
                    map.put("message", "文件已存在");
                    return map;
                }
            }
            //判断传过来是否有同名的文件或文件夹
            if (set.size()!=localpathlist.length){
                map.put("code", 1);
                map.put("message", "上传文件中有同名文件或文件夹存在");
                return map;
            }
            //得到所有的文件大小的总和之后要和该租户下的数据库储存空间大小进行比对
            Tenan tenan = tenanService.getStorageById(Integer.valueOf(tenanid));
            Long storage = tenan.getStorage();
            //得到已经已经用的储存空间大小
            String totalSize = fileUploadService.getTotalSize(Integer.valueOf(tenanid));
            if (totalSize == null || "".equals(totalSize)) {
                totalSize = "0";
            }
            long remainStorage = storage - Long.valueOf(totalSize);
            if (size > remainStorage) {
                map.put("code", 1);
                map.put("message", "存储空间不足");
                return map;
            }
            String param = "file";

            //上传腾讯对象存储
            map = fileUploadService.uploadFileLocal(multipartFiles, localfilepath, realPath, user, father, param, 0);
            logger.info("文件上传结束");
            return map;

        } catch (Exception e) {
            logger.info("文件上传数据库异常" + e);
            map.put("code", 1);
            map.put("message", "文件上传数据库异常");
            e.printStackTrace();
            return map;
        }
    }

    /**
     * 上传视频
     * 业务：根据前端传过来的视频流，先存到本地服务器上，然后在本地以流的形式上传到
     * 云服务器上，再根据返回来的结果进行存储到数据库中。
     *
     * @param request 接收文件的请求
     * @return
     */
    @RequestMapping(value = "/uploadVideo", method = RequestMethod.POST)
    public String uploadVideo(MultipartHttpServletRequest request, String tenanid, String userid) {
        ReturnMap ret = new ReturnMap();
        try {
            logger.info("文件上传开始");
            MultiValueMap<String, MultipartFile> linkedHashMap = request.getMultiFileMap();
            //上传本地路径
            String localfilepath = request.getParameter("filepath");
            logger.info("上传地址" + localfilepath);
            String father = request.getParameter("fatherPath");
            if (father == null) {
                father = "";
            }
            User user = new User();
            user.setId(Integer.valueOf(userid));
            user.setTenanid(Integer.valueOf(tenanid));
            //服务器临时目录
            String realPath = Constants.REALPATH;
            //上传文件取得
            List<MultipartFile> multipartFiles = UploadHelper.getFileSet(request, new String[]{".mp4", ".avi", ".rmvb"});
            if (linkedHashMap.get("uploadfile[]").size() != multipartFiles.size()) {
                ret.setMessage("文件类型不符！！!");
                ret.setFlg(1);
                return ret.ReturnMap();
            }
            //遍历判断所传文件的大小
            Set<String> set=new HashSet<>();
            long size=0;
            String[] localpathlist=localfilepath.split("\\|");
            int i=0;
            for (MultipartFile multipartFile : multipartFiles) {
                size+=multipartFile.getSize();
                String filename;
                if (!"undefined".equals(localpathlist[i])) {
                    //如果不为undefined 就是相对路径
                    filename = father + "" + localpathlist[i];
                    set.add(filename);
                } else {
                    //如果是undefined 就是文件名 xx.xx
                    filename = multipartFile.getOriginalFilename();
                    set.add(filename);
                }
                //判断文件是否存在
                if (!fileUploadService.selectFileRepeat(filename, Integer.valueOf(tenanid),
                        Integer.valueOf(userid), 2)) {
                    ret.setFlg(1);
                    ret.setMessage("文件已存在");
                    return ret.ReturnMap();
                }
            }
            //判断传过来是否有同名的文件或文件夹
            if (set.size()!=localpathlist.length){
                ret.setMessage("上传文件中有同名文件或文件夹存在!");
                ret.setFlg(1);
                return ret.ReturnMap();
            }
            //得到所有的文件大小的总和之后要和该租户下的数据库储存空间大小进行比对
            Tenan tenan = tenanService.getStorageById(Integer.valueOf(tenanid));
            Long storage = tenan.getStorage();
            //得到已经已经用的储存空间大小
            String totalSize = fileUploadService.getTotalSize(Integer.valueOf(tenanid));
            if (totalSize == null || "".equals(totalSize)) {
                totalSize = "0";
            }
            long remainStorage = storage - Long.valueOf(totalSize);
            if (size > remainStorage) {
                ret.setMessage("储存空间不足！！!");
                ret.setFlg(1);
                return ret.ReturnMap();
            }
            Integer type = 2;
            //上传腾讯对象存储
            ReturnMap uploadRet = fileUploadService.uploadVideoFileLocal(multipartFiles, localfilepath, realPath, user, father, type);
            //返回结果
            return uploadRet.ReturnMap();

        } catch (Exception e) {
            logger.info("数据库异常");
            ret.setFlg(1);
            ret.setMessage("数据库异常");
            e.printStackTrace();
        }
        return null;


    }

    /**
     * 下载文件
     * 业务：根据文件的id获取文件的remotePath，然后调用下载的方法，把该文件按照数据库的目录形式下载到
     * 本地的相应目录之下。
     *
     * @param id 需要下载的文件
     * @return
     */
    @RequestMapping(value = "/downloadFile")
    public String downloadFile(Integer id, HttpServletRequest request) {
        logger.info("下载文件开始===" + "id===" + id);
        ReturnMap ret = new ReturnMap();
        try { //获取到要转换的文件
            Filetable filetable = fileManagerService.selectById(id);
            Integer userid = filetable.getUserid();
            Integer tenanid = filetable.getTenanid();
            User user = new User();
            user.setId(userid);
            user.setTenanid(tenanid);
            //获得到真实的路径
            String relpath = Constants.REALPATH;
            //下载相应的文件到相应的目录之下
            fileUploadService.downloadFile(id, relpath, user, "file");
            ret.setFlg(0);
            ret.setMessage("文件下载成功");
        } catch (Exception e) {
            e.printStackTrace();
            ret.setMessage("下载文件失败");
            ret.setFlg(2);
        }
        logger.info("下载文件结束===");
        return ret.ReturnMap();
    }

    /**
     * * 文件回退
     * 业务:通过id，找到其父文件的文件地址
     * 将于其父文件文件路径相同的文件返回
     * 将父文件夹的id和路径也一并返回，如
     * id和路径都为空 则在根目录下无法返回
     *
     * @param filetable 文件的实体类
     * @param request   请求
     * @param start     从第几个开始
     * @param length    每页多少条
     * @return
     */
    @RequestMapping("/backoff")
    public Map<String, Object> backoff(Filetable filetable, HttpServletRequest request,
                                       @RequestParam(required = false, defaultValue = "1") int start,
                                       @RequestParam(required = false, defaultValue = "10") int length) {
        logger.info("文件回退开始 文件id=" + filetable.getId() + "搜索内容" + request.getParameter("search[value]") +
                "启始页" + start + "条数" + length);
        String searchValue = request.getParameter("search[value]");
        String flag = request.getParameter("flag");
        Map<String, Object> map = new HashMap<>();
        try {
            Filetable filetableID = new Filetable();
            filetableID.setId(filetable.getId());
            Filetable filetableMessage = recycleService.getFiletable(filetableID);
            PageInfo<Filetable> pageInfo = fileUploadService.backoffHtml(filetableMessage, flag, searchValue, start, length);
            PageInfo<Filetable> pageInfoStart = fileManagerService.selectInitFileListByParameter(filetableMessage, flag,start, length, searchValue);
            String fatherPath = null;
            String fatherid = null;
            Filetable fatherMessage = new Filetable();
            if (filetableMessage.getLocalpath() == null || "".equals(filetableMessage.getLocalpath())) {
                fatherPath = "";
            } else {
                if (filetableMessage.getLocalpath().equals(filetableMessage.getLocalpath().substring(0, filetableMessage.getLocalpath().indexOf("/") + 1))) {
                    fatherMessage.setFilename(filetableMessage.getLocalpath().substring(0, filetableMessage.getLocalpath().lastIndexOf("/")));
                    fatherMessage.setLocalpath("");
                    fatherMessage.setType(filetableMessage.getType());
                    fatherMessage.setDelflg(filetableMessage.getDelflg());
                    fatherMessage.setUserid(filetableMessage.getUserid());
                    fatherMessage.setTenanid(filetableMessage.getTenanid());
                    fatherMessage.setSuffix("");
                } else {
                    String name = filetableMessage.getLocalpath().substring(0, filetableMessage.getLocalpath().lastIndexOf("/"));
                    fatherMessage.setFilename(name.substring(name.lastIndexOf("/") + 1));
                    fatherMessage.setLocalpath(name.substring(0, name.lastIndexOf('/') + 1));
                    fatherMessage.setType(filetableMessage.getType());
                    fatherMessage.setDelflg(filetableMessage.getDelflg());
                    fatherMessage.setUserid(filetableMessage.getUserid());
                    fatherMessage.setTenanid(filetableMessage.getTenanid());
                    fatherMessage.setSuffix("");
                }
            }
            if (filetableMessage.getLocalpath() == "" || filetableMessage.getLocalpath() == null) {
                map.put("code", 0);
                map.put("id", "");
                map.put("localPath", "");
                map.put("recordsTotal", pageInfoStart.getTotal());
                map.put("recordsFiltered", pageInfoStart.getTotal());
                map.put("data", pageInfoStart.getList());
                return map;
            }
            //判断父文件还是否存在
            Integer count = fileUploadService.selectFileName(fatherMessage);

            if (count == 0) {
                map.put("code", 0);
                map.put("id", "");
                map.put("localPath", "");
                map.put("recordsTotal", pageInfoStart.getTotal());
                map.put("recordsFiltered", pageInfoStart.getTotal());
                map.put("data", pageInfoStart.getList());
                return map;
            }
            Filetable filetableput = fileUploadService.getFiletable(fatherMessage);
            String path = filetableput.getLocalpath() + "" + filetableput.getFilename();
            map.put("localPath", ">" + path.replaceAll("/", ">"));
            map.put("id", filetableput.getId());
            map.put("recordsTotal", pageInfo.getTotal());
            map.put("recordsFiltered", pageInfo.getTotal());
            map.put("data", pageInfo.getList());
            logger.info("文件回退结束！");
            map.put("code", 0);
            map.put("message", "文件回退成功");
            return map;
        } catch (Exception e) {
            logger.info("异常信息为=" + e);
            e.printStackTrace();
            map.put("code", 2);
            map.put("message", "文件回退异常");
            return map;
        }
    }

    /**
     * 文件转换
     * 业务：上传的时候是根据id获取文件名和文件路径进行下载后拆分，分为doc和pdf的拆分形式，
     * 根据文件id的获取该文件的后缀名，判断文件的格式，然后把该文件从远端下载到本地上，
     * 存到相应的目录下，然后对下载后的这个文件进行拆分，先拆成html的形式，然后上传到远端
     * 的服务器上，从服务器上得到她的远端地址，然后把拆分的html的远端地址放入一个数组里面，
     * 再进行txt的拆分，拆分完之后把相应的远端地址写到txt中，然后再进行上传到云服务器上。
     *
     * @param id 文件id
     * @return
     */
    @RequestMapping(value="/convertFile")
    public String convertFile(Integer id, HttpServletRequest request) {
        ReturnMap ret=new ReturnMap();
        List<String> remoteList=new ArrayList<>();
        String realpath="";
        //获取到要转换的文件
        try {
            Filetable filetable=fileManagerService.selectById(id);
            //然后进行拆分得到uuid
            //http://publictest-1253363526.file.myqcloud.com/file/11b173346a0546918ef4b452f10493d9.doc
            Integer userid=filetable.getUserid();
            Integer tenanid=filetable.getTenanid();
            String oldFileName=filetable.getFilename();
            String localpath=filetable.getLocalpath();
            User user=new User();
            user.setId(userid);
            user.setTenanid(tenanid);
            //获得到真实的路径
            realpath=Constants.REALPATH;
            fileUploadService.downloadFile(id, realpath, user, "file");
            //已下载完成，得到本地路径
            String filename=realpath + "upload" + File.separator + "file" + File.separator + filetable.getLocalpath() + filetable.getFilename() + "." + filetable.getSuffix();
            //输出的路径
            String outpath=filename.substring(0, filename.lastIndexOf("."));
            //然后判断文件类型
            if ("doc".equals(filetable.getSuffix())) {
                //如果是doc文件的话。
                //先进行转成html，然后根据返回的地址来进行txt的拆分，获取集合

                POIConverter converter=new POIConverter();
                List<Integer> list=SplitterArray.docSplitterArry(filename);
                //集合转换成数组。拆分段落的数组
                Integer[] integers=list.toArray(new Integer[0]);
                //进行html的拆分,拆分完成后放到指定的目录下,获得时间的时间戳
                String dateFile=converter.parse2html(filename, outpath, integers);
                //然后把该目录下的所有文件进行上传
                String path=outpath + "_" + dateFile;
                //进行文件夹的建立
                if (localpath == null) {
                    Filetable f=new Filetable();
                    f.setSuffix("");
                    f.setSize("");
                    f.setUserid(userid);
                    f.setTenanid(tenanid);
                    f.setType(1);
                    f.setFilename(oldFileName + "_" + dateFile);
                    f.setLocalpath("");
                    f.setDelflg(0);
                    fileManagerService.saveFolder(f);
                } else {
                    fileUploadService.createFolder(tenanid, userid, localpath + oldFileName + "_" + dateFile + "/", "", 1);
                }
                //删除云服务该文件夹图片
                File file=new File(path);
                File[] tempList=file.listFiles();//这个是目录下的所有的文件。
                //然后遍历进行上传，分为文件和图片的形式。
                List<String> picnameList=new ArrayList<>();
                for (int i=0; i < tempList.length; i++) {
                    //判断是图片还是文件
                    String tempFile=tempList[i].toString();
                    //进行图片和文件的上传
                    String suffix=tempFile.substring(tempFile.lastIndexOf(".") + 1);
                    if (suffix.contains("png") || suffix.contains("jpg") || suffix.contains("gif")) {
                        String bs=fileManagerService.base64Convert(tempFile);
                        File newPicFile=new File(tempFile);
                        String picName=newPicFile.getName();
                        //得到图片名和base64相关联的字符串。
                        String newPic=picName + ">" + bs;
                        picnameList.add(newPic);
                    }
                }
                //然后再对其遍历，进行html的化成字符串。
                for (int i=0; i < tempList.length; i++) {
                    //判断是图片还是文件
                    String tempFile=tempList[i].toString();
                    String suffix=tempFile.substring(tempFile.lastIndexOf(".") + 1);
                    if (suffix.contains("html")) {
                        //得到html的字符串
                        File file1=new File(tempFile);
                        BufferedReader bf=new BufferedReader(new FileReader(file1));
                        String content="";
                        StringBuilder sb=new StringBuilder();
                        while (content != null) {
                            content=bf.readLine();
                            if (content == null) {
                                break;
                            }
                            sb.append(content.trim());
                        }
                        bf.close();
                        logger.info("查看html内容结束！");
                        String objecthtml=sb.toString();
                        //logger.info("转换后的字符串====" + objecthtml);

                        //得到html之后把是src下的路径进行替换,进行匹配然后进行插入。
                        //主要用的是jsoup
                        Document doc=Jsoup.parse(objecthtml);
                        Elements pngs=doc.select("img[src]");
                        for (Element element : pngs) {
                            String imgUrl=element.attr("src");
                            for (int j=0; j < picnameList.size(); j++) {
                                String name=picnameList.get(j);
                                String basicName=name.substring(0, name.lastIndexOf(">"));
                                String baseName=name.substring(name.lastIndexOf(">") + 1);
                                if (imgUrl.equals(basicName)) {
                                    //得到图片的本地下载路径。
                                    String headBase64="";
                                    if (basicName.contains("png")) {
                                        headBase64="data:image/png;base64,";
                                    } else if (basicName.contains("jpg")) {
                                        headBase64="data:image/jpg;base64,";
                                    } else if (basicName.contains("gif")) {
                                        headBase64="data:image/gif;base64,";
                                    }
                                    imgUrl=headBase64 + baseName;
                                    element.attr("src", imgUrl);
                                    // logger.info("urlPath" + imgUrl);
                                }
                            }
                        }
                        String returnHtml=doc.toString();
                        String dest="";
                        Pattern p=Pattern.compile("\\n|\\r|\\r\\n");
                        Matcher m=p.matcher(returnHtml);
                        dest=m.replaceAll("");
                        //logger.info("拆分后的html字符串===" + dest);
                        //然后重新写入到html中；
                        fileUploadService.writeFile(tempFile, dest);
                        //进行上传
                        Filetable newFiletable=fileUploadService.uploadConvert(tempFile, realpath, user);
                        String remotepath=newFiletable.getRemotepath();
                        String newfilename=newFiletable.getFilename();
                        logger.info("远端路径===" + remotepath);
                        remoteList.add(remotepath + ">" + newfilename);
                    }
                }
                //进行txt的转换，首先要得到每一个的远程地址。
                String newOutpath=outpath + "_" + dateFile;
                logger.info("进行txt转换newoutpath==" + newOutpath);
                String[] remoteparam=remoteList.toArray(new String[0]);
                TxtSplitter.txtSplitter(filename, newOutpath, remoteparam, integers);
                //转换后进行上传
                File[] txtList=file.listFiles();//这个是目录下的所有的文件。
                logger.info("txtList===" + txtList);
                //然后遍历进行上传，分为文件的形式。
                for (int i=0; i < txtList.length; i++) {
                    String txtFile=txtList[i].toString();
                    if (txtFile.contains(".txt")) {
                        fileUploadService.uploadConvert(txtFile, realpath, user);
                    }
                }
                //然后进行删除这个文件夹下的文件和doc源文件
                //要删除的文件夹
                String deletefilePath=realpath + "upload" + File.separator + "file";
                fileUploadService.deleteAllFile(new File(deletefilePath));
                ret.setMessage("转换成功");
                ret.setFlg(0);

            } else if ("docx".equals(filetable.getSuffix())) {
                //如果是docx文件
                //1.先进行html的拆分
                //返回文件夹的时间戳类型。
                String dateFile=docxSplitter.docxsplithtml(filename, "2");
                //进行文件夹的建立
                if (localpath == null) {
                    Filetable f=new Filetable();
                    f.setSuffix("");
                    f.setSize("");
                    f.setUserid(userid);
                    f.setTenanid(tenanid);
                    f.setType(1);
                    f.setFilename(oldFileName + "_" + dateFile);
                    f.setLocalpath("");
                    f.setDelflg(0);
                    fileManagerService.saveFolder(f);
                } else {
                    fileUploadService.createFolder(tenanid, userid, localpath + oldFileName + "_" + dateFile + "/", "", 1);
                }
                //进行上传到云服务器上。
                String path=outpath + "_" + dateFile;
                File file=new File(path);
                File[] tempList=file.listFiles();//这个是目录下的所有的文件。
                //然后遍历进行上传，分为文件和图片的形式。
                for (int i=0; i < tempList.length; i++) {
                    String tempFile=tempList[i].toString();
                    //进行html的上传
                    Filetable newFiletable=fileUploadService.uploadConvert(tempFile, realpath, user);
                    String remotepath=newFiletable.getRemotepath();
                    String newfilename=newFiletable.getFilename();
                    logger.info("远端路径===" + remotepath);
                    remoteList.add(remotepath + ">" + newfilename);
                }
                //进行txt的转换，首先要得到每一个的远程地址。
                String[] remoteparam=remoteList.toArray(new String[0]);
                docxSplitter.docxsplitTxt(filename, "2", remoteparam, dateFile);
                File[] txtList=file.listFiles();//这个是目录下的所有的文件。
//                logger.info("txtList===" + txtList);
                //然后遍历进行上传，分为文件和图片的形式。
                for (int i=0; i < txtList.length; i++) {
                    String txtFile=txtList[i].toString();
                    if (txtFile.contains(".txt")) {
                        fileUploadService.uploadConvert(txtFile, realpath, user);
                    }
                }
                //删除文件夹。
                String deletefilePath=realpath + File.separator + "upload" + File.separator + "file";
                fileUploadService.deleteAllFile(new File(deletefilePath));
                ret.setMessage("转换成功");
                ret.setFlg(0);

            } else if ("pdf".equals(filetable.getSuffix())) {
                PdfUtils pdfUtils=new PdfUtils();
                //如果是pdf文件,进行转化
                //先进行拆分为html,存到指定的路径下
                logger.info("filename===" + filename);
                String dateFile=pdfUtils.PdfPaging(filename);
                //进行文件夹的建立
                if (localpath == null) {
                    Filetable f=new Filetable();
                    f.setSuffix("");
                    f.setSize("");
                    f.setUserid(userid);
                    f.setTenanid(tenanid);
                    f.setType(1);
                    f.setFilename(oldFileName + "_" + dateFile);
                    f.setLocalpath("");
                    f.setDelflg(0);
                    fileManagerService.saveFolder(f);
                } else {
                    fileUploadService.createFolder(tenanid, userid, localpath + oldFileName + "_" + dateFile + "/", "", 1);
                }
                String path=outpath + "_" + dateFile;
                File file=new File(path);
                //这个是目录下的所有的文件。
                File[] tempFileList=file.listFiles();
                //然后进行上传拆分后的html，返回远端路径。
                for (int i=0; i < tempFileList.length; i++) {
                    String tempFile=tempFileList[i].toString();
                    logger.info("进入上传pdf html的方法");
                    Filetable newFiletable=fileUploadService.uploadConvert(tempFile, realpath, user);
                    logger.info("出来上传 PDF html的方法");
                    String remotepath=newFiletable.getRemotepath();
                    String newfilename=newFiletable.getFilename();
                    logger.info("remotepath======" + remotepath);
                    if (remotepath.contains(".html")) {
                        remoteList.add(remotepath + ">" + newfilename);
                    }
                }
                //进行txt的拆分
                String[] remoteparam=remoteList.toArray(new String[0]);
                pdfUtils.convertTxt(filename, remoteparam, dateFile);
                //然后对txt进行上传。
                //这个是目录下的所有的文件。
                File[] txtList=file.listFiles();
                //然后遍历进行上传，分为文件和图片的形式。
                for (int i=0; i < txtList.length; i++) {
                    String txtFile=txtList[i].toString();
                    if (txtFile.contains(".txt")) {
                        logger.info("进入上传 pdf txt的方法");
                        fileUploadService.uploadConvert(txtFile, realpath, user);
                        logger.info("出来上传pdf txt的方法");
                    }
                }
                //然后进行删除这个文件夹下的文件和doc源文件
                //要删除的文件夹
                String deletefilePath=realpath + "upload/" + "file";
                fileUploadService.deleteAllFile(new File(deletefilePath));
                ret.setMessage("转换成功");
                ret.setFlg(0);
            }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            ret.setFlg(2);
            ret.setMessage("此文件无法转换!");
        }
        return ret.ReturnMap();
    }

    /**
     * 通过文件的uuid或者是文件id获取html
     * 业务：前端传过来所要查看的html的id 或者 uuid，然后分为uuid和id的情况，主要是获取html的路径，
     * 然后根据路径下载这个html文件，顺便下载它的所有图片，然后用base64编码的格式，把这些图片
     * 重新编码，然后把本地的HTML文件化成字符串的形式，替换里面相应位置的图片为base64编码的形式，
     * 然后把相应的字符串转给前端。
     *
     * @param id   文件id
     * @param uuid 文件的uuid
     * @return
     */
    @RequestMapping(value = "/editHtml")
    public String editHtml(Integer id, String uuid, HttpServletRequest request) {
        logger.info("通过文件的uuid或者是文件id获取html开始===id===" + id + "===uuid===" + uuid);
        ReturnMap ret = new ReturnMap();
        Filetable filetable = new Filetable();
        String relpath = Constants.REALPATH;
        String outPath = relpath + "upload" + File.separator + "html";
        //获得服务器的真实地址
        try {
            //如果是用文件id来查的
            if (uuid == null || "".equals(uuid)) {
                //通过id获取该条信息。
                //然后对这个HTML进行下载下来，包括这个目录下的所有的图片
                filetable = fileManagerService.selectById(id);
                Integer userid = filetable.getUserid();
                String remotePath = filetable.getRemotepath();
                String newRemotePath = remotePath.substring(remotePath.lastIndexOf("/"));
                Integer tenanid = filetable.getTenanid();
                User user = new User();
                user.setId(userid);
                user.setTenanid(tenanid);
                //此时只需要进行通过remote进行下载就可以了
                fileUploadService.downloadRemoteHtml(id, relpath, user, "html");
                String newHtmlPath = relpath + "upload" + File.separator + "html" + File.separator + newRemotePath;
                //传到另一个服务器上的方法
                String originLocalPath = relpath + "upload" + File.separator + "html";
//                //然后把本地的文件上传到另一个服务器上
//                fileUploadService.remoteConnection(originLocalPath);
                File file = new File(newHtmlPath);
                BufferedReader bf = new BufferedReader(new FileReader(file));
                String content = "";
                StringBuilder sb = new StringBuilder();
                while (content != null) {
                    content = bf.readLine();
                    if (content == null) {
                        break;
                    }
                    sb.append(content.trim());
                }
                bf.close();
                logger.info("查看html内容结束！");
                String objecthtml = sb.toString();
                logger.info("转换后的字符串====" + objecthtml);
//                //删除本地的下载的所有文件
//                fileUploadService.deleteAllFile(new File(outPath));
                Map<String, Object> map = new HashMap<>();
                map.put("data", objecthtml);
                ret.setFlg(0);
                ret.setMessage("html文件浏览成功");
                ret.setData(JSONArray.fromObject(map).toString());
            } else {
                //如果是用uuid来浏览的话
                String remotePath = Util.wcmserver + "/html/" + uuid + ".html";
                //然后根据remotepath进行查询信息
                filetable.setRemotepath(remotePath);
                filetable.setDelflg(0);
                filetable = fileManagerService.selectOne(filetable);
                Integer userid = filetable.getUserid();
                Integer tenanid = filetable.getTenanid();
                Integer newid = filetable.getId();
                User user = new User();
                user.setId(userid);
                user.setTenanid(tenanid);
                //此时只需要进行通过remote进行下载就可以了
                fileUploadService.downloadRemoteHtml(newid, relpath, user, "html");
                String newHtmlPath = relpath + "upload" + File.separator + "html" + File.separator + uuid + ".html";
                logger.info("新的html===" + newHtmlPath);
                //传到另一个服务器上的方法
                String originLocalPath = relpath + "upload" + File.separator + "html";
//                //然后把本地的文件上传到另一个服务器上
//                fileUploadService.remoteConnection(originLocalPath);
                File file = new File(newHtmlPath);
                BufferedReader bf = new BufferedReader(new FileReader(file));
                String content = "";
                StringBuilder sb = new StringBuilder();
                while (content != null) {
                    content = bf.readLine();
                    if (content == null) {
                        break;
                    }
                    sb.append(content.trim());
                }
                bf.close();
//                fileUploadService.deleteAllFile(new File(outPath));
                Map<String, Object> map = new HashMap<>();
                logger.info("查看html内容结束！");
                String objecthtml = sb.toString();
                logger.info("转换后的字符串====" + objecthtml);
                map.put("data", objecthtml);
                ret.setFlg(0);
                ret.setMessage("html文件浏览成功");
                ret.setData(JSONArray.fromObject(map).toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
            ret.setFlg(2);
            ret.setMessage("html文件浏览失败");
        }
        logger.info("通过文件的uuid或者是文件id获取html结束===id===" + id + "===uuid===" + uuid);
        return ret.ReturnMap();
    }

    /**
     * 浏览网页
     * 业务：1，主要区分是用id还是用uuid的形式来输入。
     * 2.分为拆分后的和未拆分的，因为doc拆分会出现图片的形式
     * 3.就是把要浏览的网页下载到本地，然后给前端返回路径。
     * 4，注意浏览后服务器会出现很多垃圾软件，所以当他进行再次浏览的时候就先删除垃圾文件。
     *
     * @param id      文件id
     * @param uuid    uuid
     * @param request
     * @return
     */
    @RequestMapping(value = "/glanceHtml")
    public String glanceHtml(Integer id, String uuid, HttpServletRequest request) {
        logger.info("浏览文件开始====id" + id + "===uuid===" + uuid);
        ReturnMap ret = new ReturnMap();
        Filetable filetable = new Filetable();
        String relpath = Constants.REALPATH;
        //获得服务器的真实地址
        try {
            //如果是用文件id来查的
            if (uuid == null || "".equals(uuid)) {
                //通过id获取该条信息。
                //通过id获取该条信息。
                //然后对这个HTML进行下载下来，包括这个目录下的所有的图片
                filetable = fileManagerService.selectById(id);
                Integer userid = filetable.getUserid();
                String remotePath = filetable.getRemotepath();
                String newRemotePath = remotePath.substring(remotePath.lastIndexOf("/"));
                Integer tenanid = filetable.getTenanid();
                User user = new User();
                user.setId(userid);
                user.setTenanid(tenanid);
                //此时只需要进行通过remote进行下载就可以了
                fileUploadService.downloadRemoteHtml(id, relpath, user, "html");
                String newHtmlPath = relpath + "upload" + File.separator + "html" + File.separator + newRemotePath;
                //传到另一个服务器上的方法
                String originLocalPath = relpath + "upload" + File.separator + "html";
//                //然后把本地的文件上传到另一个服务器上
//                fileUploadService.remoteConnection(originLocalPath);
//                //删除本地的下载的所有文件
//                fileUploadService.deleteAllFile(new File(originLocalPath));
                String htmlPath="upload/"+"html"+newRemotePath;
                logger.info("html的地址======" + htmlPath);
                //然后下载图片到本地。
                String url = htmlPath;
                Map<String, Object> map = new HashMap<>();
                map.put("data", url);
                ret.setFlg(0);
                ret.setMessage("返回url成功");
                ret.setData(JSONObject.fromObject(map).toString());
            } else {
                //用uuid来查看
                String remotePath = Util.wcmserver + "/html/" + uuid + ".html";
                //然后根据remotepath进行查询信息
                filetable.setRemotepath(remotePath);
                filetable.setDelflg(0);
                filetable = fileManagerService.selectOne(filetable);
                Integer userid = filetable.getUserid();
                Integer tenanid = filetable.getTenanid();
                Integer newid = filetable.getId();
                User user = new User();
                user.setId(userid);
                user.setTenanid(tenanid);
                //此时只需要进行通过remote进行下载就可以了
                fileUploadService.downloadRemoteHtml(newid, relpath, user, "html");
                String newHtmlPath = relpath + "upload" + File.separator + "html" + File.separator + uuid + ".html";
                logger.info("新的html===" + newHtmlPath);
                //传到另一个服务器上的方法
                String originLocalPath = relpath + "upload" + File.separator + "html";
//                //然后把本地的文件上传到另一个服务器上
//                fileUploadService.remoteConnection(originLocalPath);
//                //删除本地的下载的所有文件
//                fileUploadService.deleteAllFile(new File(originLocalPath));
                String htmlPath = "upload/html/"+uuid+".html";
                String url = htmlPath;
                Map<String, Object> map = new HashMap<>();
                map.put("data", url);
                ret.setFlg(0);
                ret.setMessage("返回url成功");
                ret.setData(JSONObject.fromObject(map).toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
            ret.setFlg(2);
            ret.setMessage("返回url失败");
            logger.info("异常类型是" + e);
        }
        return ret.ReturnMap();
    }
    /**
     * 上传之后的删除文件
     * 业务：1.主要是文件上传之后的弹框里面的删除按钮，当点击删除的时候把该文件从文件列表中删除；
     * 2.此时要判断是在文件夹里面的文件还是在根目录下的文件。
     *
     * @param fatherid 父目录的id
     * @param tenanid  租户id
     * @param userid   用户id
     * @param filename 文件名字
     * @return
     */
    @RequestMapping(value = "/deleteFileByName")
    public String deleteFileByName(String fatherid, String tenanid, String userid, String filename) {
        logger.info("进入删除已上传文件的方法==fatherid=="+fatherid+"==tenanid=="+tenanid+"==userid=="+userid+"==filename=="+filename);
        ReturnMap ret = new ReturnMap();
        try {
            //判断fatherid是否为空 ，如果为空的话说明在根目录下
            Integer type = 0;
            fileManagerService.deleteFileByName(fatherid, Integer.valueOf(tenanid), Integer.valueOf(userid), filename, type);
            ret.setFlg(0);
            ret.setMessage("删除上传后的文件成功");
        } catch (Exception e) {
            e.printStackTrace();
            ret.setFlg(2);
            ret.setMessage("删除上传后的文件失败");
            logger.info("异常类型是" + e);
        }
        logger.info("删除已上传文件的方法结束==fatherid==" + fatherid + "==tenanid==" + tenanid + "==userid==" + userid + "==filename==" + filename);
        return ret.ReturnMap();

    }
}
